home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / DockStrip / MoreInterfaceLib / MoreInterfaceLib.c next >
Encoding:
Text File  |  2000-06-24  |  30.4 KB  |  813 lines

  1. /*
  2.     File:        MoreInterfaceLib.c
  3.  
  4.     Contains:    Compatibility shim for routines not in InterfaceLib.
  5.  
  6.     Written by:    Quinn
  7.  
  8.     Copyright:    Copyright © 1999 by Apple Computer, Inc., all rights reserved.
  9.  
  10.                 You may incorporate this Apple sample source code into your program(s) without
  11.                 restriction. This Apple sample source code has been provided "AS IS" and the
  12.                 responsibility for its operation is yours. You are not permitted to redistribute
  13.                 this Apple sample source code as "Apple sample source code" after having made
  14.                 changes. If you're going to re-distribute the source, we require that you make
  15.                 it clear in the source that the code was descended from Apple sample source
  16.                 code, but that you've made changes.
  17.  
  18.     Change History (most recent first):
  19.  
  20.         <11>    18/10/99    Quinn   Convert MoreAssert's to, more correct, MoreAssertQ's.
  21.         <10>     16/9/99    Quinn   Add FSM FCB accessors.
  22.          <9>     16/8/99    Quinn   Added comment about nasty restriction with MorePBRemoteAccess.
  23.          <8>     22/7/99    Quinn   Use correct ProcInfo in MoreAddDrive.
  24.          <7>     15/6/99    Quinn   Added MoreBlockZero.
  25.          <6>     15/6/99    Quinn   Fixed Gestalt Value glue for pre-8.5 systems.  Added Extended
  26.                                     Disk Init Package routines.
  27.          <5>     22/4/99    Quinn   Added PBRemoteAccess.
  28.          <4>     20/4/99    Quinn   Added Gestalt Value routines.
  29.          <3>     16/3/99    Quinn   Added MoreUTFindDrive and MoreAddDrive.  Also fixed some mixups
  30.                                     about which traps are toolbox traps and which aren't.
  31.          <2>      1/3/99    Quinn   Added MoreFlushCodeCacheRange.  Also some general tidy up.
  32.          <1>     25/2/99    Quinn   First checked in.
  33. */
  34.  
  35. /////////////////////////////////////////////////////////////////
  36. // MoreIsBetter Setup
  37.  
  38. #include "MoreSetup.h"
  39.  
  40. /////////////////////////////////////////////////////////////////
  41. // Mac OS Interfaces
  42.  
  43. #include <CodeFragments.h>
  44. #include <LowMem.h>
  45. #include <Traps.h>
  46. #include <FSM.h>
  47. #include <Gestalt.h>
  48. #include <DiskInit.h>
  49.  
  50. /////////////////////////////////////////////////////////////////
  51. // Our Prototypes
  52.  
  53. #include "MoreInterfaceLib.h"
  54.  
  55. /////////////////////////////////////////////////////////////////
  56.  
  57. // This file contains implementations of various Mac OS API routines
  58. // that were rolled in to InterfaceLib as of Mac OS 8.5.  They are
  59. // in the InterfaceLib stub library as of Universal Interfaces 3.2.
  60. // This code does the magic to decide whether the routine is available
  61. // via InterfaceLib, or whether we have to synthesise our own MixedMode
  62. // glue (or, in some cases, implementation).
  63.  
  64. // If you use any of the routines in this library, you must either:
  65. //
  66. // a) continue to hard link to InterfaceLib, in which case you won't
  67. //    launch on pre-8.5 systems (with a cryptic error message), or
  68. // b) weak link to InterfaceLib, in which case you must check that you're
  69. //    on 8.5 or later before calling any of these routine lest
  70. //    you die by trying to call nil.
  71.  
  72. // You can change the definition of the following compiler variable,
  73. // which causes these routine to always use the InterfaceLib variant.
  74. // You'd better make sure they're available, as described above.
  75.  
  76. #ifndef MORE_MAC_OS_8_5_OR_LATER
  77.     #define MORE_MAC_OS_8_5_OR_LATER 0
  78. #endif
  79.  
  80. // Also, Universal Interfaces 3.2 defines macros for some missing
  81. // low memory accessors.  For CFM code, these macros override
  82. // the external procedure definition.  So you can no longer
  83. // call the real accessors, even if you do depend on Mac OS 8.5
  84. // or greater.  This hack fixes the problem.  [Radar ID 2308604]
  85.  
  86. #undef LMGetUnitTableEntryCount
  87. #undef LMSetUnitTableEntryCount
  88.  
  89. /////////////////////////////////////////////////////////////////
  90.  
  91. #if TARGET_RT_MAC_CFM
  92.  
  93. extern pascal SInt16 MoreLMGetUnitTableEntryCount(void)
  94. {
  95.     if (MORE_MAC_OS_8_5_OR_LATER || (LMGetUnitTableEntryCount != (void *) kUnresolvedCFragSymbolAddress)) {
  96.         return LMGetUnitTableEntryCount();
  97.     } else {
  98.         return *((SInt16 *) 0x01d2);
  99.     }
  100. }
  101.  
  102. extern pascal void   MoreLMSetUnitTableEntryCount(SInt16 value)
  103. {
  104.     if (MORE_MAC_OS_8_5_OR_LATER || (LMSetUnitTableEntryCount != (void *) kUnresolvedCFragSymbolAddress)) {
  105.         LMSetUnitTableEntryCount(value);
  106.     } else {
  107.         *((SInt16 *) 0x01d2) = value;
  108.     }
  109. }
  110.  
  111. #endif
  112.  
  113. /////////////////////////////////////////////////////////////////
  114. // Mixed Mode ProcInfo Helper
  115.  
  116. // Bit Numbers
  117. //
  118. //  3         2         1         0
  119. // 10987654321098765432109876543210
  120.  
  121. // Stack Based Layout
  122. //
  123. //                             cccc <- calling convention = kPascalStackBased (0), kCStackBased (1), kThinkCStackBased (5)
  124. //                           ss     <- result size
  125. //                         ss       <- stack parameter 1 size
  126. //                       ss         <- stack parameter 2 size
  127. //                     ss           <- stack parameter 3 size
  128. //                   ss             <- stack parameter 4 size
  129. //                 ss               <- stack parameter 5 size
  130. //               ss                 <- stack parameter 6 size
  131. //             ss                   <- stack parameter 7 size
  132. //           ss                     <- stack parameter 8 size
  133. //         ss                       <- stack parameter 9 size
  134. //       ss                         <- stack parameter 10 size
  135. //     ss                           <- stack parameter 11 size
  136. //   ss                             <- stack parameter 12 size
  137.  
  138. // Register Based Layout
  139. //
  140. //                             cccc <- calling convention = kRegisterBased (2)
  141. //                      rrrss       <- register result location and size
  142. //                 rrrss            <- register parameter 1 location and size
  143. //            rrrss                 <- register parameter 1 location and size
  144. //       rrrss                      <- register parameter 1 location and size
  145. //  rrrss                           <- register parameter 1 location and size
  146.  
  147. // Dispatched Stack Based Layout
  148. //
  149. //                             cccc <- calling convention = kD0DispatchedPascalStackBased (8), kD1DispatchedPascalStackBased (12), kD0DispatchedCStackBased (9), kStackDispatchedPascalStackBased (14)
  150. //                           ss     <- result size
  151. //                         ss       <- selector size
  152. //                       ss         <- stack parameter 1 size
  153. //                     ss           <- stack parameter 2 size
  154. //                   ss             <- stack parameter 3 size
  155. //                 ss               <- stack parameter 4 size
  156. //               ss                 <- stack parameter 5 size
  157. //             ss                   <- stack parameter 6 size
  158. //           ss                     <- stack parameter 7 size
  159. //         ss                       <- stack parameter 8 size
  160. //       ss                         <- stack parameter 9 size
  161. //     ss                           <- stack parameter 10 size
  162. //   ss                             <- stack parameter 11 size
  163.  
  164. // Special Case Layout
  165. //
  166. //                             cccc <- calling convention = kSpecialCase (15)
  167. //                       xxxxxx     <- special case selector (see "MixedMode.h")
  168.  
  169. // Values for "ss":
  170. //
  171. // 00 = kNoByteCode
  172. // 01 = kOneByteCode
  173. // 10 = kTwoByteCode
  174. // 11 = kFourByteCode
  175.  
  176. // Values for "rrr":
  177. //
  178. //
  179. // 000 = kRegisterD0
  180. // 001 = kRegisterD1
  181. // 010 = kRegisterD2
  182. // 011 = kRegisterD3
  183. // 100 = kRegisterA0
  184. // 101 = kRegisterA1
  185. // 110 = kRegisterA2
  186. // 111 = kRegisterA3
  187.  
  188. /////////////////////////////////////////////////////////////////
  189.  
  190. #if TARGET_RT_MAC_CFM
  191.  
  192. // DriverInstallReserveMem is a bit trickier to implement than the
  193. // previous two routines.  Basically we have get the address of the
  194. // _DriverInstall ($A03D) trap and then call it using
  195. // CallOSTrapUniversalProc.  There are a number of important things
  196. // to note here:
  197. //   a) We can just get the trap address and treat it as a UPP.
  198. //      The trap tables are defined to contain UPPs, either pointers
  199. //      to real 68K code, or pointers to a routine descriptor (if
  200. //      the trap is native or fat).
  201. //   b) We must use CallOSTrapUniversalProc, not CallUniversalProc.
  202. //      CallOSTrapUniversalProc automatically does a number of things 
  203. //      that are very critical for call OS traps.  See "IM:PowerPC
  204. //      System Software", p2-42 for a full description.
  205. //   c) When calling OS traps from PPC, it's important to get the
  206. //      ProcInfo right.  Specifically, all OS traps assume an
  207. //      implicit parameter of D1 as the first parameter.  After
  208. //      that, the parameters should be defined in the order that
  209. //      they are declared in the prototype.  If you fail to get
  210. //      the order right, or to put D1 first, your code will work,
  211. //      up until it encounters someone who has patched the OS trap
  212. //      with a native or fat patch.  Then strange things will happen,
  213. //      and you'll spend hours in MacsBug trying to figure it out.
  214.  
  215. // The trap number and ProcInfo description for DriverInstallReserveMem.
  216.  
  217. enum {
  218.     _DriverInstallReserveMem = 0x0A43D
  219. };
  220.  
  221. enum {
  222.     uppDriverInstallProcInfo = kRegisterBased
  223.         | REGISTER_RESULT_LOCATION(kRegisterD0)
  224.         | RESULT_SIZE(SIZE_CODE(sizeof(OSErr)))
  225.         | REGISTER_ROUTINE_PARAMETER(1, kRegisterD1, SIZE_CODE(sizeof(long)))
  226.         | REGISTER_ROUTINE_PARAMETER(2, kRegisterA0, SIZE_CODE(sizeof(DRVRHeaderPtr)))
  227.         | REGISTER_ROUTINE_PARAMETER(3, kRegisterD0, SIZE_CODE(sizeof(short)))
  228. };
  229.  
  230. // IMPORTANT: Previous versions of TradDriverLoaderLib defined parameter 1
  231. // as sizeof(short), not sizeof(long).  I fixed this based on information
  232. // I extracted from the official Apple version of this glue, in the 
  233. // InterfaceLib implementation on Mac OS 8.5.
  234.  
  235. extern pascal OSErr  MoreDriverInstallReserveMem(DRVRHeaderPtr drvrPtr, DriverRefNum refNum)
  236. {
  237.     if (MORE_MAC_OS_8_5_OR_LATER || (DriverInstallReserveMem != (void *) kUnresolvedCFragSymbolAddress)) {
  238.         return DriverInstallReserveMem(drvrPtr, refNum);
  239.     } else {
  240.         UniversalProcPtr trapAddress;
  241.         
  242.         // Check that I've got the ProcInfo correct.  This magic value
  243.         // was extracted from InterfaceLib on Mac OS 8.5.
  244.  
  245.         MoreAssertQ(uppDriverInstallProcInfo == 0x00533822);
  246.         
  247.         trapAddress = GetOSTrapAddress(_DriverInstallReserveMem);
  248.         return CallOSTrapUniversalProc(trapAddress, uppDriverInstallProcInfo, _DriverInstallReserveMem, drvrPtr, refNum);
  249.     }
  250. }
  251.  
  252. #endif
  253.  
  254. /////////////////////////////////////////////////////////////////
  255.  
  256. #if TARGET_RT_MAC_CFM
  257.  
  258. enum {
  259.     uppFlushCodeCacheRangeProcInfo = kRegisterBased |
  260.             RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) |
  261.             REGISTER_RESULT_LOCATION(kRegisterD0) |
  262.             REGISTER_ROUTINE_PARAMETER(1, kRegisterD0, SIZE_CODE(sizeof(long))) |
  263.             REGISTER_ROUTINE_PARAMETER(2, kRegisterD1, SIZE_CODE(sizeof(long))) |
  264.             REGISTER_ROUTINE_PARAMETER(3, kRegisterA0, SIZE_CODE(sizeof(void *))) |
  265.             REGISTER_ROUTINE_PARAMETER(4, kRegisterA1, SIZE_CODE(sizeof(unsigned long)))
  266. };
  267.  
  268. extern pascal OSErr  MoreFlushCodeCacheRange(void *address, unsigned long count)
  269. {
  270.     if (MORE_MAC_OS_8_5_OR_LATER || (FlushCodeCacheRange != (void *) kUnresolvedCFragSymbolAddress)) {
  271.         return FlushCodeCacheRange(address, count);
  272.     } else {
  273.         UniversalProcPtr trapAddress;
  274.         
  275.         // Check that I've got the ProcInfo correct.  This magic value
  276.         // was extracted from InterfaceLib on Mac OS 8.5.
  277.  
  278.         MoreAssertQ(uppFlushCodeCacheRangeProcInfo == 0x5e671822);
  279.         
  280.         trapAddress = GetOSTrapAddress(_HWPriv);
  281.         return CallOSTrapUniversalProc(trapAddress, uppFlushCodeCacheRangeProcInfo, 9, _HWPriv, address, count);
  282.     }
  283. }
  284.  
  285. #endif
  286.  
  287. /////////////////////////////////////////////////////////////////
  288.  
  289. #if TARGET_RT_MAC_CFM
  290.  
  291. enum {
  292.     uppUTFindDriveProcInfo = kD0DispatchedPascalStackBased |
  293.             RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) |
  294.             DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(SIZE_CODE(sizeof(long))) |
  295.             DISPATCHED_STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(SInt16))) |
  296.             DISPATCHED_STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(DrvQElPtr *))),
  297.     uppUTLocateFCBProcInfo = kD0DispatchedPascalStackBased
  298.              | RESULT_SIZE(SIZE_CODE(sizeof(OSErr)))
  299.              | DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kFourByteCode)
  300.              | DISPATCHED_STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(VCBPtr)))
  301.              | DISPATCHED_STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(unsigned long)))
  302.              | DISPATCHED_STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(StringPtr)))
  303.              | DISPATCHED_STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(short*)))
  304.              | DISPATCHED_STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(FCBRecPtr*))),
  305.     uppUTLocateNextFCBProcInfo = kD0DispatchedPascalStackBased
  306.              | RESULT_SIZE(SIZE_CODE(sizeof(OSErr)))
  307.              | DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kFourByteCode)
  308.              | DISPATCHED_STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(VCBPtr)))
  309.              | DISPATCHED_STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(unsigned long)))
  310.              | DISPATCHED_STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(StringPtr)))
  311.              | DISPATCHED_STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(short*)))
  312.              | DISPATCHED_STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(FCBRecPtr*))),
  313.     uppUTIndexFCBProcInfo = kD0DispatchedPascalStackBased
  314.              | RESULT_SIZE(SIZE_CODE(sizeof(OSErr)))
  315.              | DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kFourByteCode)
  316.              | DISPATCHED_STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(VCBPtr)))
  317.              | DISPATCHED_STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(short*)))
  318.              | DISPATCHED_STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(FCBRecPtr*))),
  319.     uppUTResolveFCBProcInfo = kD0DispatchedPascalStackBased
  320.              | RESULT_SIZE(SIZE_CODE(sizeof(OSErr)))
  321.              | DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kFourByteCode)
  322.              | DISPATCHED_STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short)))
  323.              | DISPATCHED_STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(FCBRecPtr*)))
  324. };
  325.  
  326. extern pascal OSErr MoreUTFindDrive(SInt16 driveNum, DrvQElPtr *driveQElementPtr)
  327. {
  328.     #if !TARGET_CPU_68K
  329.         if (MORE_MAC_OS_8_5_OR_LATER || (UTFindDrive != (void *) kUnresolvedCFragSymbolAddress)) {
  330.             return UTFindDrive(driveNum, driveQElementPtr);
  331.         } else
  332.     #endif
  333.         {
  334.             UniversalProcPtr trapAddress;
  335.             
  336.             // Check that I've got the ProcInfo correct.  This magic value
  337.             // was extracted from InterfaceLib on Mac OS 8.5.
  338.  
  339.             MoreAssertQ(uppUTFindDriveProcInfo == 0x0EE8);
  340.             
  341.             trapAddress = GetToolTrapAddress(_HFSUtilDispatch);
  342.             return CallUniversalProc(trapAddress, uppUTFindDriveProcInfo, 15, driveNum, driveQElementPtr);
  343.         }
  344. }
  345.  
  346. extern pascal OSErr MoreUTLocateFCB(VCBPtr                 volCtrlBlockPtr,
  347.                                  unsigned long             fileNum,
  348.                                  StringPtr                 namePtr,
  349.                                  short *                fileRefNum,
  350.                                  FCBRecPtr *            fileCtrlBlockPtr)
  351. {
  352.     #if !TARGET_CPU_68K
  353.         if (MORE_MAC_OS_8_5_OR_LATER || (UTLocateFCB != (void *) kUnresolvedCFragSymbolAddress)) {
  354.             return UTLocateFCB(volCtrlBlockPtr, fileNum, namePtr, fileRefNum, fileCtrlBlockPtr);
  355.         } else
  356.     #endif
  357.         {
  358.             UniversalProcPtr trapAddress;
  359.             
  360.             // Check that I've got the ProcInfo correct.  This magic value
  361.             // was extracted from InterfaceLib on Mac OS 8.5.
  362.  
  363.             MoreAssertQ(uppUTLocateFCBProcInfo == 0x03FFE8);
  364.             
  365.             trapAddress = GetToolTrapAddress(_HFSUtilDispatch);
  366.             return CallUniversalProc(trapAddress, uppUTLocateFCBProcInfo, 2, volCtrlBlockPtr, fileNum, namePtr, fileRefNum, fileCtrlBlockPtr);
  367.         }
  368. }
  369.  
  370. extern pascal OSErr MoreUTLocateNextFCB(VCBPtr             volCtrlBlockPtr,
  371.                                  unsigned long             fileNum,
  372.                                  StringPtr                 namePtr,
  373.                                  short *                fileRefNum,
  374.                                  FCBRecPtr *            fileCtrlBlockPtr)
  375. {
  376.     #if !TARGET_CPU_68K
  377.         if (MORE_MAC_OS_8_5_OR_LATER || (UTLocateNextFCB != (void *) kUnresolvedCFragSymbolAddress)) {
  378.             return UTLocateNextFCB(volCtrlBlockPtr, fileNum, namePtr, fileRefNum, fileCtrlBlockPtr);
  379.         } else
  380.     #endif
  381.         {
  382.             UniversalProcPtr trapAddress;
  383.             
  384.             // Check that I've got the ProcInfo correct.  This magic value
  385.             // was extracted from InterfaceLib on Mac OS 8.5.
  386.  
  387.             MoreAssertQ(uppUTLocateNextFCBProcInfo == 0x03FFE8);
  388.             
  389.             trapAddress = GetToolTrapAddress(_HFSUtilDispatch);
  390.             return CallUniversalProc(trapAddress, uppUTLocateNextFCBProcInfo, 3, volCtrlBlockPtr, fileNum, namePtr, fileRefNum, fileCtrlBlockPtr);
  391.         }
  392. }
  393.  
  394. extern pascal OSErr MoreUTIndexFCB(VCBPtr                 volCtrlBlockPtr,
  395.                                  short *                fileRefNum,
  396.                                  FCBRecPtr *            fileCtrlBlockPtr)
  397. {
  398.     #if !TARGET_CPU_68K
  399.         if (MORE_MAC_OS_8_5_OR_LATER || (UTIndexFCB != (void *) kUnresolvedCFragSymbolAddress)) {
  400.             return UTIndexFCB(volCtrlBlockPtr, fileRefNum, fileCtrlBlockPtr);
  401.         } else
  402.     #endif
  403.         {
  404.             UniversalProcPtr trapAddress;
  405.             
  406.             // Check that I've got the ProcInfo correct.  This magic value
  407.             // was extracted from InterfaceLib on Mac OS 8.5.
  408.  
  409.             MoreAssertQ(uppUTIndexFCBProcInfo == 0x03FE8);
  410.             
  411.             trapAddress = GetToolTrapAddress(_HFSUtilDispatch);
  412.             return CallUniversalProc(trapAddress, uppUTIndexFCBProcInfo, 4, volCtrlBlockPtr, fileRefNum, fileCtrlBlockPtr);
  413.         }
  414. }
  415.  
  416. extern pascal OSErr MoreUTResolveFCB(short                 fileRefNum,
  417.                                  FCBRecPtr *            fileCtrlBlockPtr)
  418. {
  419.     #if !TARGET_CPU_68K
  420.         if (MORE_MAC_OS_8_5_OR_LATER || (UTResolveFCB != (void *) kUnresolvedCFragSymbolAddress)) {
  421.             return UTResolveFCB(fileRefNum, fileCtrlBlockPtr);
  422.         } else
  423.     #endif
  424.         {
  425.             UniversalProcPtr trapAddress;
  426.             
  427.             // Check that I've got the ProcInfo correct.  This magic value
  428.             // was extracted from InterfaceLib on Mac OS 8.5.
  429.  
  430.             MoreAssertQ(uppUTResolveFCBProcInfo == 0x0EE8);
  431.             
  432.             trapAddress = GetToolTrapAddress(_HFSUtilDispatch);
  433.             return CallUniversalProc(trapAddress, uppUTResolveFCBProcInfo, 5, fileRefNum, fileCtrlBlockPtr);
  434.         }
  435. }
  436.  
  437. #endif
  438.  
  439. /////////////////////////////////////////////////////////////////
  440.  
  441. #if TARGET_RT_MAC_CFM
  442.  
  443. enum {
  444.     uppAddDriveProcInfo = kRegisterBased |
  445.             RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) |
  446.             REGISTER_RESULT_LOCATION(kRegisterD0) |
  447.             REGISTER_ROUTINE_PARAMETER(1, kRegisterD1, SIZE_CODE(sizeof(short))) |
  448.             REGISTER_ROUTINE_PARAMETER(2, kRegisterA0, SIZE_CODE(sizeof(DrvQElPtr))) |
  449.             REGISTER_ROUTINE_PARAMETER(3, kRegisterD0, SIZE_CODE(sizeof(long)))
  450. };
  451.  
  452. // Some comments about the ProcInfo value:
  453. //
  454. // o It's set to return a result even though the high-level glue doesn't.
  455. //   This is because the trap returns a result in D0.  We can safely ignored
  456. //   it from the C code.
  457. //
  458. // o The D1 parameter is listed as sizeof(short), not sizeof(long) which is
  459. //   the size used by most other OS traps.  The reason: I'm not sure.
  460. //   Come to think of it, sizeof(short) makes more sense to me because
  461. //   that's what trap words are.  Anyway, I'm just parroting what
  462. //   InterfaceLib 8.5 does; my specific goal is to make CFM patches to
  463. //   AddDrive work properly, which requires that we all use identical
  464. //   ProcInfo's.
  465. //
  466. // o Register D0 contains the drvrRefNum and drvNum parameters combined,
  467. //   with drvNum in the high word and drvrRefNum in the low word.
  468. //   Oh, those wacky 68K calling conventions (-:
  469.  
  470. extern pascal void MoreAddDrive(DriverRefNum drvrRefNum, SInt16 drvNum, DrvQElPtr qEl)
  471. {
  472.     UInt32 response;
  473.     
  474.     if ( MORE_MAC_OS_8_5_OR_LATER || ((Gestalt(gestaltSystemVersion, (SInt32 *) &response) == noErr) && (response >= 0x0850))) {
  475.         AddDrive(drvrRefNum, drvNum, qEl);
  476.     } else {
  477.         UniversalProcPtr trapAddress;
  478.  
  479.         // Prior to Mac OS 8.5, the InterfaceLib glue for AddDrive was
  480.         // messed up, so we have to roll our own.
  481.         
  482.         // Check that I've got the ProcInfo correct.  This magic value
  483.         // was extracted from InterfaceLib on Mac OS 8.5.
  484.  
  485.         MoreAssertQ(uppAddDriveProcInfo == 0x0733022);
  486.         
  487.         trapAddress = GetOSTrapAddress(_AddDrive);
  488.         (void) CallOSTrapUniversalProc(trapAddress, uppAddDriveProcInfo, _AddDrive, qEl, ( ((UInt32) drvNum) << 16) | (UInt16) drvrRefNum);
  489.     }
  490. }
  491.  
  492. #else
  493.  
  494. // Unlike most of these glue routines, the 68K version of AddDrive 
  495. // is implemented as link-in glue.  Thus there are no inlines in the
  496. // interface file.  We therefore have to implement this routine for
  497. // classic 68K, as a simple call through to the real routine.
  498.  
  499. extern pascal void MoreAddDrive(DriverRefNum drvrRefNum, SInt16 drvNum, DrvQElPtr qEl)
  500. {
  501.     AddDrive(drvrRefNum, drvNum, qEl);
  502. }
  503.  
  504. #endif
  505.  
  506. /////////////////////////////////////////////////////////////////
  507.  
  508. #if TARGET_RT_MAC_CFM
  509.  
  510. enum {
  511.     _GestaltValue = 0xABF1
  512. };
  513.  
  514. enum {
  515.     uppNewGestaltValueProcInfo = kD0DispatchedPascalStackBased |
  516.             RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) |
  517.             DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(SIZE_CODE(sizeof(short))) |
  518.             DISPATCHED_STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(OSType))) |
  519.             DISPATCHED_STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long))),
  520.     uppReplaceGestaltValueProcInfo = kD0DispatchedPascalStackBased |
  521.             RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) |
  522.             DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(SIZE_CODE(sizeof(short))) |
  523.             DISPATCHED_STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(OSType))) |
  524.             DISPATCHED_STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long))),
  525.     uppSetGestaltValueProcInfo = kD0DispatchedPascalStackBased |
  526.             RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) |
  527.             DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(SIZE_CODE(sizeof(short))) |
  528.             DISPATCHED_STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(OSType))) |
  529.             DISPATCHED_STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long))),
  530.     uppDeleteGestaltValueProcInfo = kD0DispatchedPascalStackBased |
  531.             RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) |
  532.             DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(SIZE_CODE(sizeof(short))) |
  533.             DISPATCHED_STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(OSType)))
  534. };
  535.  
  536. // The glue I use here is especially cheesy.  In general, I try
  537. // to avoid using the pre-processor for generating bogus C syntax,
  538. // ie I only use #if where I could syntactically use if().  However,
  539. // in this case I've been forced to break my own rules.  The problem
  540. // is that NewGestaltValue etc are not present in Universal Interface's
  541. // 3.2 InterfaceLib for CFM-68K.  Why?  I don't know for sure, but it
  542. // could be because they are only available in the real InterfaceLib for
  543. // Mac OS 8.5 and higher, and that can't be run on 68K machines.  Anyway,
  544. // given that they're not available in InterfaceLib, you can't reference
  545. // the symbol in the CFM-68K build, which requires ugly preprocessor
  546. // stuff.  There may be a better way of doing this, but I'm pushed for
  547. // time right now.  I hope to revisit it eventually.
  548. // -- Quinn, 20 Apr 1999
  549.  
  550. extern pascal OSErr MoreNewGestaltValue(OSType selector, long newValue)
  551. {
  552.     #if !TARGET_CPU_68K
  553.         if (MORE_MAC_OS_8_5_OR_LATER || (NewGestaltValue != (void *) kUnresolvedCFragSymbolAddress)) {
  554.             return NewGestaltValue(selector, newValue);
  555.         } else
  556.     #endif
  557.         {
  558.             UniversalProcPtr trapAddress;
  559.             
  560.             // Check that I've got the ProcInfo correct.  This magic value
  561.             // was extracted from InterfaceLib on Mac OS 8.5.
  562.  
  563.             MoreAssertQ(uppNewGestaltValueProcInfo == 0x00000FA8);
  564.             
  565.             trapAddress = GetToolboxTrapAddress(_GestaltValue);
  566.             return CallUniversalProc(trapAddress, uppNewGestaltValueProcInfo, 0x0401, selector, newValue);
  567.         }
  568. }
  569.  
  570. extern pascal OSErr MoreReplaceGestaltValue(OSType selector, long replacementValue)
  571. {
  572.     #if !TARGET_CPU_68K
  573.         if (MORE_MAC_OS_8_5_OR_LATER || (ReplaceGestaltValue != (void *) kUnresolvedCFragSymbolAddress)) {
  574.             return ReplaceGestaltValue(selector, replacementValue);
  575.         } else
  576.     #endif
  577.         {
  578.             UniversalProcPtr trapAddress;
  579.             
  580.             // Check that I've got the ProcInfo correct.  This magic value
  581.             // was extracted from InterfaceLib on Mac OS 8.5.
  582.  
  583.             MoreAssertQ(uppReplaceGestaltValueProcInfo == 0x00000FA8);
  584.             
  585.             trapAddress = GetToolboxTrapAddress(_GestaltValue);
  586.             return CallUniversalProc(trapAddress, uppReplaceGestaltValueProcInfo, 0x0402, selector, replacementValue);
  587.         }
  588. }
  589.  
  590. extern pascal OSErr MoreSetGestaltValue(OSType selector, long newValue)        
  591. {
  592.     #if !TARGET_CPU_68K
  593.         if (MORE_MAC_OS_8_5_OR_LATER || (SetGestaltValue != (void *) kUnresolvedCFragSymbolAddress)) {
  594.             return SetGestaltValue(selector, newValue);
  595.         } else
  596.     #endif
  597.         {
  598.             UniversalProcPtr trapAddress;
  599.             
  600.             // Check that I've got the ProcInfo correct.  This magic value
  601.             // was extracted from InterfaceLib on Mac OS 8.5.
  602.  
  603.             MoreAssertQ(uppSetGestaltValueProcInfo == 0x00000FA8);
  604.             
  605.             trapAddress = GetToolboxTrapAddress(_GestaltValue);
  606.             return CallUniversalProc(trapAddress, uppSetGestaltValueProcInfo, 0x0404, selector, newValue);
  607.         }
  608. }
  609.  
  610. extern pascal OSErr MoreDeleteGestaltValue(OSType selector)
  611. {
  612.     #if !TARGET_CPU_68K
  613.         if (MORE_MAC_OS_8_5_OR_LATER || (DeleteGestaltValue != (void *) kUnresolvedCFragSymbolAddress)) {
  614.             return DeleteGestaltValue(selector);
  615.         } else
  616.     #endif
  617.         {
  618.             UniversalProcPtr trapAddress;
  619.             
  620.             // Check that I've got the ProcInfo correct.  This magic value
  621.             // was extracted from InterfaceLib on Mac OS 8.5.
  622.  
  623.             MoreAssertQ(uppDeleteGestaltValueProcInfo == 0x000003A8);
  624.             
  625.             trapAddress = GetToolboxTrapAddress(_GestaltValue);
  626.             return CallUniversalProc(trapAddress, uppDeleteGestaltValueProcInfo, 0x0203, selector);
  627.         }
  628. }
  629.  
  630. #endif
  631.  
  632. /////////////////////////////////////////////////////////////////
  633.  
  634. #if TARGET_RT_MAC_CFM
  635.  
  636. // Golly, this one is ugly.  In prior to ARA 3.0, this trap was
  637. // implemented by 68K code that used D0 as a selector.  But
  638. // with ARA 3.0, this trap is implemented by PowerPC code whose
  639. // ProcInfo doesn't include the D0 selector.  So, you can either
  640. // declare the ProcInfo to include the selector, and then you won't
  641. // work with ARA 3.0 and higher, or you can declare it without
  642. // the selector, in which case register D0 won't be set up
  643. // and you won't work with ARA < 3.0.  Nasty.
  644. //
  645. // The long term solution is to check the version number of ARA
  646. // and do the right thing for each version.  Alas, I don't have
  647. // time to code and test that solution.  So I'm sticking with
  648. // the ARA 3.x solution for the moment.
  649. //
  650. // Bletch!
  651. //
  652. // Quinn, 16 Aug 1999
  653.  
  654. enum {
  655.     _RemoteAccess = 0xAA5B
  656. };
  657.  
  658. enum {
  659.     uppPBRemoteAccessProcInfo = kPascalStackBased
  660.          | RESULT_SIZE(SIZE_CODE(sizeof(OSErr)))
  661.          | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(TPRemoteAccessParamBlock)))
  662.          | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Boolean)))
  663. };
  664.  
  665. extern pascal OSErr MorePBRemoteAccess(TPRemoteAccessParamBlock paramBlock, Boolean async)
  666.     // There is still no InterfaceLib entry for PBRemoteAccess, so
  667.     // we always do the CallUniversalProc thing.
  668. {
  669.     UniversalProcPtr trapAddress;
  670.     
  671.     trapAddress = GetToolboxTrapAddress(_RemoteAccess);
  672.     return CallUniversalProc(trapAddress, uppPBRemoteAccessProcInfo, paramBlock, async);
  673. }
  674.  
  675. #endif
  676.  
  677. /////////////////////////////////////////////////////////////////
  678.  
  679. #if TARGET_RT_MAC_CFM
  680.  
  681. enum {
  682.     uppDIXFormatProcInfo = kStackDispatchedPascalStackBased |
  683.             RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) |
  684.             DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(SIZE_CODE(sizeof(short))) |
  685.             DISPATCHED_STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short))) |
  686.             DISPATCHED_STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Boolean))) |
  687.             DISPATCHED_STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(unsigned long))) |
  688.             DISPATCHED_STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(unsigned long *))),
  689.     uppDIXZeroProcInfo = kStackDispatchedPascalStackBased |
  690.             RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) |
  691.             DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(SIZE_CODE(sizeof(short))) |
  692.             DISPATCHED_STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short))) |
  693.             DISPATCHED_STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(ConstStr255Param))) |
  694.             DISPATCHED_STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(short))) |
  695.             DISPATCHED_STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(short))) |
  696.             DISPATCHED_STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(short))) |
  697.             DISPATCHED_STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(unsigned long))) |
  698.             DISPATCHED_STACK_ROUTINE_PARAMETER(7, SIZE_CODE(sizeof(void *))),
  699.     uppDIReformatProcInfo = kStackDispatchedPascalStackBased |
  700.             RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) |
  701.             DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(SIZE_CODE(sizeof(short))) |
  702.             DISPATCHED_STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short))) |
  703.             DISPATCHED_STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(short))) |
  704.             DISPATCHED_STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(ConstStr255Param))) |
  705.             DISPATCHED_STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(ConstStr255Param)))
  706. };
  707.  
  708. // These routines use the same cheesy glue structure as the Gestalt Value
  709. // routines, for much the same reasons.  See the comment above MoreNewGestaltValue
  710. // for more details.
  711.  
  712. extern pascal OSErr MoreDIXFormat(     short                     drvNum,
  713.                                      Boolean                 fmtFlag,
  714.                                      unsigned long             fmtArg,
  715.                                      unsigned long *        actSize)
  716. {
  717.     #if !TARGET_CPU_68K
  718.         if (MORE_MAC_OS_8_5_OR_LATER || (DIXFormat != (void *) kUnresolvedCFragSymbolAddress)) {
  719.             return DIXFormat(drvNum, fmtFlag, fmtArg, actSize);
  720.         } else
  721.     #endif
  722.         {
  723.             UniversalProcPtr trapAddress;
  724.             
  725.             // Check that I've got the ProcInfo correct.  This magic value
  726.             // was extracted from InterfaceLib on Mac OS 8.5.
  727.  
  728.             MoreAssertQ(uppDIXFormatProcInfo == 0x0000F6AE);
  729.             
  730.             trapAddress = GetToolboxTrapAddress(_Pack2);
  731.             return CallUniversalProc(trapAddress, uppDIXFormatProcInfo, 0x000C, drvNum, fmtFlag, fmtArg, actSize);
  732.         }
  733. }
  734.  
  735. extern pascal OSErr MoreDIXZero(     short                     drvNum,
  736.                                      ConstStr255Param         volName,
  737.                                      short                     fsid,
  738.                                      short                     mediaStatus,
  739.                                      short                     volTypeSelector,
  740.                                      unsigned long             volSize,
  741.                                      void *                    extendedInfoPtr)
  742. {
  743.     #if !TARGET_CPU_68K
  744.         if (MORE_MAC_OS_8_5_OR_LATER || (DIXZero != (void *) kUnresolvedCFragSymbolAddress)) {
  745.             return DIXZero(drvNum, volName, fsid, mediaStatus, volTypeSelector, volSize, extendedInfoPtr);
  746.         } else
  747.     #endif
  748.         {
  749.             UniversalProcPtr trapAddress;
  750.             
  751.             // Check that I've got the ProcInfo correct.  This magic value
  752.             // was extracted from InterfaceLib on Mac OS 8.5.
  753.  
  754.             MoreAssertQ(uppDIXZeroProcInfo == 0x003EAEAE);
  755.             
  756.             trapAddress = GetToolboxTrapAddress(_Pack2);
  757.             return CallUniversalProc(trapAddress, uppDIXZeroProcInfo, 0x000E, drvNum, volName, fsid, mediaStatus, volTypeSelector, volSize, extendedInfoPtr);
  758.         }
  759. }
  760.  
  761.  
  762. extern pascal OSErr MoreDIReformat(     short                     drvNum,
  763.                                      short                     fsid,
  764.                                      ConstStr255Param         volName,
  765.                                      ConstStr255Param         msgText)
  766. {
  767.     #if !TARGET_CPU_68K
  768.         if (MORE_MAC_OS_8_5_OR_LATER || (DIReformat != (void *) kUnresolvedCFragSymbolAddress)) {
  769.             return DIReformat(drvNum, fsid, volName, msgText);
  770.         } else
  771.     #endif
  772.         {
  773.             UniversalProcPtr trapAddress;
  774.             
  775.             // Check that I've got the ProcInfo correct.  This magic value
  776.             // was extracted from InterfaceLib on Mac OS 8.5.
  777.  
  778.             MoreAssertQ(uppDIReformatProcInfo == 0x0000FAAE);
  779.             
  780.             trapAddress = GetToolboxTrapAddress(_Pack2);
  781.             return CallUniversalProc(trapAddress, uppDIReformatProcInfo, 0x0010, drvNum, fsid, volName, msgText);
  782.         }
  783. }
  784.  
  785. #endif
  786.  
  787. /////////////////////////////////////////////////////////////////
  788.  
  789. // the routine uses the same cheesy glue structure as the Gestalt Value
  790. // routines, for much the same reasons.  See the comment above MoreNewGestaltValue
  791. // for more details.
  792.  
  793. extern pascal void MoreBlockZero(void * destPtr, Size byteCount)
  794. {
  795.     #if TARGET_RT_MAC_CFM && !TARGET_CPU_68K
  796.         if (MORE_MAC_OS_8_5_OR_LATER || (BlockZero != (void *) kUnresolvedCFragSymbolAddress)) {
  797.             BlockZero(destPtr, byteCount);
  798.         } else 
  799.     #endif
  800.         {
  801.             UInt8 *cursor;
  802.             
  803.             cursor = (UInt8 *) destPtr;
  804.             while (byteCount != 0) {
  805.                 *cursor = 0;
  806.                 cursor += 1;
  807.                 byteCount -= 1;
  808.             }
  809.         }
  810. }
  811.  
  812. /////////////////////////////////////////////////////////////////
  813.